package models;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.Entity;
import javax.persistence.ManyToOne;
import javax.persistence.Transient;

import org.hibernate.mapping.Array;

import flexjson.JSONSerializer;

import play.data.validation.Required;
import play.db.jpa.Model;

@Entity
public class Symenu extends Model {

	@Required
	public String text;
	
	public String url;
	
	@ManyToOne
	public Symenu parentMenu;
	
	@Transient
	public long parentId;
	@Transient
	public String parentText;
	
	@Transient
	public boolean isexpand;		//下拉树，是否选中
	
	@Transient
	public boolean ischecked;

	public boolean getIschecked() {
		return this.ischecked;
	}

	public void setIschecked(boolean ischecked) {
		this.ischecked = ischecked;
	}
	
	public boolean getIsexpand(){
		return true;
	}
	
	
	public String getParentText(){
		return this.parentMenu==null?"":this.parentMenu.text;
	}
	
	public long getParentId(){
		return this.parentMenu==null?0:this.parentMenu.id;
	}
	
	@Override
	public String toString() {
		return text+":"+url;
	}
	
	/**
	 * 管理员维护菜单，展示菜单树
	 * @return 所有菜单的ligerUi菜单样式json字符串.
	 */
	public static String allMenuJson(List<Symenu> rootMenus) {
		String json = "";
		
		for(Symenu symenu : rootMenus){
			String menuJson = toJson(symenu);
			String childJosn = toJson(symenu.findChild());
			if("".equals(childJosn)){
				menuJson = menuJson.replaceAll("}$",",\"children\":[]},");
			}else{
				menuJson = menuJson.replaceAll("}$",",\"children\":"+childJosn+"},");
			}
			json+=menuJson;
		}
		return "{\"Rows\":["+json.replaceAll(",$","")+"]}";
	}
	
	/**
	 * 选中 role 对应的symenu
	 * @param rootMenus
	 * @param r
	 * @return
	 */
	public static String selectedRoleMenu(List<Symenu> rootMenus,Role r){
		String json = "";
		for(Symenu symenu : rootMenus){
			String menuJson = toJson(symenu);
			String childJosn = toJson(symenu.findChild(),r);
			if("".equals(childJosn)){
				menuJson = menuJson.replaceAll("}$",",\"children\":[]},");
			}else{
				menuJson = menuJson.replaceAll("}$",",\"children\":"+childJosn+"},");
			}
			json+=menuJson;
		}
		return "{\"Rows\":["+json.replaceAll(",$","")+"]}";
	}
	
	/**
	 * 如果 role 已绑定菜单，则设置ischecked 为  true
	 * @param symenus
	 * @param r
	 * @return
	 */
	public static String toJson(List<Symenu> symenus,Role r){
		if(symenus==null || symenus.isEmpty()){
			return "";
		}
		List<Symenu> rms = RoleMenu.getMenuByRole(r);

		List<Symenu> symenu2 = new ArrayList<Symenu>();
		for(Symenu symenu : symenus){
			if(rms.contains(symenu)){
				symenu.setIschecked(true);
			}else{
				symenu.setIschecked(false);
			}
			symenu2.add(symenu);
		}
		return  new JSONSerializer()
		.include("id", "text","url", "parentId","parentText","ischecked")
		.exclude("*").serialize(symenu2);
	}
	
	/**
	 * 登录后展示全部菜单树
	 * @param rootMenus
	 * @return
	 */
	public static String showMenuByUser(User u){
		//所有菜单树
//		return allMenuJson(Symenu.findParentPoint()).replace("{\"Rows\":","").replaceAll("}$", "");
		List<Role> roles = Role.findByUser(u);
		List<Symenu> roleHaveMenus = Symenu.findByRoles(roles);
		List<Symenu> rootMenus = new ArrayList<Symenu>();
		for(Symenu menu : roleHaveMenus){
			if(menu.isRoot()){
				rootMenus.add(menu);
			}
		}
		return "["+createShowMenuJson(rootMenus,roleHaveMenus).replaceAll(",$","")+"]";
	}
	
	/**
	 * 父节点对应的子节点包含于 roleHaveMenus 中才展现json
	 * @param rootMenus 父节点
	 * @param roleHaveMenus 包含的节点
	 * @return json
	 */
	private static String createShowMenuJson(List<Symenu> rootMenus,
			List<Symenu> roleHaveMenus) {
		String json = "";
		for(Symenu rootMenu : rootMenus){
			List<Symenu> rootChilds = Symenu.find("parentMenu=?", rootMenu).fetch();
			List<Symenu> haveChilds = new ArrayList<Symenu>();
			for(Symenu child : rootChilds){
				if(roleHaveMenus.contains(child)){
					haveChilds.add(child);
				}
			}
			String rootJson = Symenu.toJson(rootMenu);
			String childJson = Symenu.toJson(haveChilds);
			if("".equals(childJson)){
				rootJson = rootJson.replaceAll("}$",",\"children\":[]},");
			}else{
				rootJson = rootJson.replaceAll("}$",",\"children\":"+childJson+"},");
			}
			json+=rootJson;
			
		}
		return json;
	}

	/**
	 * 是否是跟节点.
	 * @return true 是跟节点, false 不是跟节点
	 */
	public boolean isRoot(){
		return this.parentMenu==null?true:false;
	}
	
	/**
	 * 根据角色获得对应的菜单.
	 * @param rs
	 * @return
	 */
	public static List<Symenu> findByRoles(List<Role> rs){
		List<RoleMenu> rms = new ArrayList<RoleMenu>();
		List<Symenu> menus = new ArrayList<Symenu>();
		for(Role r : rs) {
			rms.addAll(RoleMenu.findByRole(r));
		}
		for(RoleMenu rm : rms){
			menus.add(rm.symenu);
		}
		
		return menus;
	}
	
	/**
	 * 获得所有父节点
	 * @return
	 */
	public static List<Symenu> findParentPoint(){
		return Symenu.find("parentMenu.id is null").fetch();
	}
	
	/**
	 * 找到该节点所有子节点
	 * @return
	 */
	public List<Symenu> findChild(){
		return Symenu.find("parentMenu=?", this).fetch();
	}
	
	public static String toJson(Symenu symenus){
		return  new JSONSerializer()
		.include("id", "text","url", "parentId","parentText","isexpand")
		.exclude("*").serialize(symenus);
	}
	
	public static String toJson(List<Symenu> symenus){
		if(symenus==null || symenus.isEmpty()){
			return "";
		}
		return  new JSONSerializer()
		.include("id", "text","url", "parentId","parentText")
		.exclude("*").serialize(symenus);
	}

}
